package com.foo.designpattern.factory.abstractfactory;

import junit.framework.TestCase;

/**
 * com.foo.designpattern.factory.abstractfactory
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-10 17:30.
 *
 * @Description 测试类：抽象工厂模式
 * 抽象工厂模式是工厂方法模式的升级版本，它用来创建一组相关或者相互依赖的对象。
 * 比如本例中，BMW320系列使用A型空调和A型发动机，而BMW523系列使用B型空调和B型发动机，
 * 那么，使用抽象工厂模式，在为BMW320系列生产相关配件时，就无需指定配件的型号，
 * 它会自动根据车型生产对应的A型的配件。
 * <p/>
 * 抽象工厂的优点：
 * 1、分离接口和实现：客户端使用抽象工厂来创建需要的对象，而客户端根本就不知道具体的实现是谁，
 * 客户端只是面向产品的接口编程而已。也就是说，客户端从具体的产品实现中解耦。
 * 2、使切换产品族变得容易：因为一个具体的工厂实现代表的一个产品族，比如从BMW320到BMW523系列只需要切换以下具体工厂。
 * 抽象工厂模式的缺点：
 * 不太容易扩展新的产品：如果需要给整个产品族添加一个新的产品，那么就需要修改抽象工厂，
 * 这样，将会导致修改所有的工厂实现类。
 * <p/>
 * 无论是简单工厂模式、工厂方法模式还是抽象工厂模式，他们都属于工厂模式，在形式和特点上也是极为相似的，
 * 他们最终目的都是为了解耦。在使用时，我们不必去在意这个模式到底是工厂方法模式还是抽象工厂方法模式，
 * 因为他们之间的演变常常是令人捉摸不透的。经常会发现，明明使用的工厂方法模式，当新需求来临，稍加修改，
 * 加入了一个新方法之后，由于类中的产品构成了不同等级结构中的产品族，它就变成抽象工厂模式了；
 * 而对于抽象工厂模式，当减少一个方法使得提供的产品不再构成产品族之后，它就演变成了工厂方法模式。
 * 所以，在使用工厂模式时，只需要关心降低耦合度的目的是否达到及可以了。
 */

public class AbstractFactoryTestCase extends TestCase {
    public void testAbstractFactory() {
        System.out.println("= = = = ↓↓↓抽象工厂模式，测试开始↓↓↓ = = = =");

        /**
         * 生产BMW320系列的配件
         * 抽象工厂自动配置A型号的发动机和A型号的空调
         */
        BMW320Factory bmw320Factory = new BMW320Factory();
        bmw320Factory.createEngine();
        bmw320Factory.createAirCondition();

        /**
         * 生产BMW523系列配件
         * 抽象工厂自动配置A型号的发动机和A型号的空调
         */
        BMW523Factory bmw523Factory = new BMW523Factory();
        bmw523Factory.createEngine();
        bmw523Factory.createAirCondition();

        System.out.println("= = = = ↑↑↑抽象工厂模式，测试结束↑↑↑ = = = =");
    }
}
